/*
 * irqproxy.c
 *
 *  Created on: 01.06.2010
 *      Author: Phil
 */


#include "irqproxy.h"
#include <board.h>
#include <aic/aic.h>
#include <FreeRTOS.h>
#include <task.h>

#include "pio_it_rtos.h"
#include "usb_task.h"

typedef void (*irqHandler)(void);
static const irqHandler irq_handler_table[32] = {
		/* FIQ          */ NULL,
		/* SYSC         */ NULL,  // serviced by FreeRTOS
		/* PIOA         */ PIO_InterruptHandler,
		/* PIOB         */ PIO_InterruptHandler,

		/* CAN0         */ NULL,
		/* CAN1         */ NULL,
		/* US0          */ NULL,
		/* US1          */ NULL,

		/* US2          */ NULL,
		/* MCI          */ NULL,
		/* TWI          */ NULL,
		/* SPI0         */ NULL,

		/* SPI1         */ NULL,
		/* SSC0         */ NULL,
		/* SSC1         */ NULL,
		/* TC0          */ NULL,

		/* TC1          */ NULL,
		/* TC2          */ NULL,
		/* TC3          */ NULL,
		/* TC4          */ NULL,

		/* TC5          */ NULL,
		/* TC6          */ NULL,
		/* TC7          */ NULL,
		/* TC8          */ NULL,

		/* ADC0         */ NULL,
		/* ADC1         */ NULL,
		/* PWMC         */ NULL,
		/* UDP          */ USBTask_InterruptHandler,

		/* AIC IRQ0     */ NULL,
		/* AIC IRQ1     */ NULL,
		/* AIC IRQ2     */ NULL,
		/* AIC IRQ3     */ NULL
};

void vIRQProxy( void )
{

	/* Save the context of the current task. */
	portSAVE_CONTEXT();

	/* Write in the IVR to support Protect Mode */
	AT91C_BASE_AIC->AIC_IVR = 0;

	{
		irqHandler irq = irq_handler_table[AT91C_BASE_AIC->AIC_ISR];
		if(irq)
		{
			(*irq)();
		}
	}

	/* Find the highest priority task that is ready to run. */
	vTaskSwitchContext();

	/* End the interrupt in the AIC. */
	AT91C_BASE_AIC->AIC_EOICR = 0;

	portRESTORE_CONTEXT();
}
